home *** CD-ROM | disk | FTP | other *** search
- //
- // Apple Macintosh Developer Technical Support
- //
- // Copyright (work in progress) Apple Computer, Inc All rights reserved.
- //
- // You may incorporate this sample code into your applications without
- // restriction, though the sample code has been provided "AS IS" and the
- // responsibility for its operation is 100% yours. However, what you are
- // not permitted to do is to redistribute the source as "DSC Sample Code"
- // after having made changes. If you're going to re-distribute the source,
- // we require that you make it clear in the source that the code was
- // descended from Apple Sample Code, but that you've made changes.
- //
-
- #include <Processes.h>
-
-
- #include "LaunchApplication.h"
-
- static OSErr FindApplicationProcess (OSType creatorToFind, ProcessSerialNumberPtr processSN);
- static OSErr FindApplicationOnDisk (OSType creatorToSearchFor, short startVRefNum, FSSpec* foundApp);
-
-
- //------------------------------------------------------------------------------------
- OSErr LaunchApplication (OSType creator)
- //------------------------------------------------------------------------------------
- {
- ProcessSerialNumber theAppPSN;
- FSSpec theAppToLaunch;
- OSErr err = noErr;
-
- // Check for already running app
-
- err = FindApplicationProcess(creator , &theAppPSN );
- if(err == noErr)
- {
- err = SetFrontProcess( &theAppPSN );
- }
- else
- {
- err = FindApplicationOnDisk (creator, 0, &theAppToLaunch);
- if(err == noErr)
- {
- LaunchParamBlockRec launchPB;
-
- launchPB.launchBlockID = extendedBlock;
- launchPB.launchEPBLength = extendedBlockLen;
- launchPB.launchFileFlags = 0;
- launchPB.launchControlFlags = launchContinue | launchNoFileFlags;
- launchPB.launchAppSpec = &theAppToLaunch;
- launchPB.launchAppParameters = nil;
-
- LaunchApplication( &launchPB );
-
- }
- }
-
- return err;
-
-
-
-
- }
-
-
-
-
- //
- // This runs through the process list looking for the requested application. It searches for
- // applications of type 'APPL', 'APPC' (control panel apps), 'APPE' (extension apps), and
- // 'APPD' (desk accessory apps). Once the requested application has been found processSN
- // will contain the process serial number of the running application that was just found.
- //
- static OSErr FindApplicationProcess (OSType creatorToFind, ProcessSerialNumberPtr processSN)
- {
- ProcessInfoRec procInfo;
- FSSpec procSpec;
- Str31 processName;
- OSErr err = noErr;
-
- // Clear out the PSN so we're starting at the beginning of the list.
- processSN->lowLongOfPSN = kNoProcess;
- processSN->highLongOfPSN = kNoProcess;
-
- // Initialize the process information record.
- procInfo.processInfoLength = sizeof (ProcessInfoRec);
- procInfo.processName = &processName[0];
- procInfo.processAppSpec = &procSpec;
-
- // Loop through all the processes until we find the process we want or
- // error out because of some reason (usually, no more processes).
- do {
- err = GetNextProcess (processSN);
- if (err == noErr) {
- err = GetProcessInformation (processSN, &procInfo);
- }
- } while ((procInfo.processSignature != creatorToFind || !(procInfo.processType == 'APPL' ||
- procInfo.processType == 'APPC' || procInfo.processType == 'appe' ||
- procInfo.processType == 'APPD')) && err == noErr);
-
- return (err);
- }
-
- //
- // Finds the requested application on disk searching the desktop database and returns an FSSpec to that app.
- // It first searches local disks, then searches remote disks. Once a possible application has been found
- // in the desktop database the application is verified to actually exist because the desktop database is
- // often not totally accurate.
- //
- // If startVRefNum is negative then it will be treated as a VRefNum and the search will start on specified
- // volume. If the value of startVRefNum is 0 or positive then the search starts on the first local disk,
- // runs through all local disks, and then searches the first remote volume and runs through all remote
- // volumes looking for the requested application.
- //
- static OSErr FindApplicationOnDisk (OSType creatorToSearchFor, short startVRefNum, FSSpec* foundApp) {
- HVolumeParam volPB;
- HIOParam paramPB;
- DTPBRec desktopPB;
- GetVolParmsInfoBuffer volinfo;
- FInfo fndrInfo;
- OSErr err = fnfErr; // default return value
-
- volPB.ioNamePtr = nil;
- paramPB.ioNamePtr = nil;
- paramPB.ioBuffer = (Ptr)&volinfo;
- paramPB.ioReqCount = sizeof (volinfo);
-
- // Try to find the application on the specified disk, if one was specified, first.
- if (startVRefNum < 0) {
- volPB.ioVolIndex = startVRefNum;
- if (PBHGetVInfoSync ((HParmBlkPtr)&volPB) == noErr) {
- // Call PBDTGetPath to find the desktop file on the volume.
- desktopPB.ioCompletion = nil;
- desktopPB.ioNamePtr = nil;
- desktopPB.ioVRefNum = volPB.ioVRefNum;
- desktopPB.ioIndex = 0; // Find the most recent application.
-
- if (PBDTGetPath (&desktopPB) == noErr) {
- desktopPB.ioFileCreator = creatorToSearchFor;
- desktopPB.ioNamePtr = (*foundApp).name;
-
- if (PBDTGetAPPLSync (&desktopPB) == noErr) {
- // At this point we think we have found the correct application.
- (*foundApp).vRefNum = volPB.ioVRefNum;
- (*foundApp).parID = desktopPB.ioAPPLParID;
-
- // Verify that this application actually exists.
- if (FSpGetFInfo (foundApp, &fndrInfo) == noErr && fndrInfo.fdCreator == creatorToSearchFor) {
- // This application actually exists, we can use it.
- err = noErr;
- }
- }
- }
- }
- }
-
- if (err != noErr) {
- // The application wasn't on the starting disk, so loop over every local volume looking for the application.
- for (volPB.ioVolIndex = 1; PBHGetVInfoSync ((HParmBlkPtr)&volPB) == noErr; volPB.ioVolIndex++) {
- // Call PBHGetVolParms call to ensure the volume is a local volume.
- paramPB.ioVRefNum = volPB.ioVRefNum;
-
- if (PBHGetVolParmsSync ((HParmBlkPtr)¶mPB) == noErr && volinfo.vMServerAdr == 0) {
- // Call PBDTGetPath to find the desktop file on the volume.
- desktopPB.ioCompletion = nil;
- desktopPB.ioNamePtr = nil;
- desktopPB.ioVRefNum = volPB.ioVRefNum;
- desktopPB.ioIndex = 0; // Find the most recent application.
-
- if (PBDTGetPath (&desktopPB) == noErr) {
- desktopPB.ioFileCreator = creatorToSearchFor;
- desktopPB.ioNamePtr = (*foundApp).name;
-
- if (PBDTGetAPPLSync (&desktopPB) == noErr) {
- // At this point we think we have found the correct application.
- (*foundApp).vRefNum = volPB.ioVRefNum;
- (*foundApp).parID = desktopPB.ioAPPLParID;
-
- // Verify that this application actually exists.
- if (FSpGetFInfo (foundApp, &fndrInfo) == noErr && fndrInfo.fdCreator == creatorToSearchFor) {
- // This application actually exists, we can use it.
- err = noErr;
- break;
- }
- }
- }
- }
- }
- }
-
- if (err != noErr) {
- // If we didn't find the application locally, check remote volumes.
-
- // Loop over every local volume looking for the application.
- for (volPB.ioVolIndex = 1; PBHGetVInfoSync ((HParmBlkPtr)&volPB) == noErr; volPB.ioVolIndex++) {
- // Call PBHGetVolParms call to ensure the volume is a remote volume.
- paramPB.ioVRefNum = volPB.ioVRefNum;
-
- if (PBHGetVolParmsSync ((HParmBlkPtr)¶mPB) == noErr && volinfo.vMServerAdr != 0) {
- // Call PBDTGetPath to find the desktop file on the volume.
- desktopPB.ioCompletion = nil;
- desktopPB.ioNamePtr = nil;
- desktopPB.ioVRefNum = volPB.ioVRefNum;
- desktopPB.ioIndex = 0; // Find the most recent application.
-
- if (PBDTGetPath (&desktopPB) == noErr) {
- desktopPB.ioFileCreator = creatorToSearchFor;
- desktopPB.ioNamePtr = (*foundApp).name;
-
- if (PBDTGetAPPLSync (&desktopPB) == noErr) {
- // At this point we have found the correct application.
- (*foundApp).vRefNum = volPB.ioVRefNum;
- (*foundApp).parID = desktopPB.ioAPPLParID;
-
- // Verify that this application actually exists.
- if (FSpGetFInfo (foundApp, &fndrInfo) == noErr && fndrInfo.fdCreator == creatorToSearchFor) {
- // This application actually exists, we can use it.
- err = noErr;
- break;
- }
- }
- }
- }
- }
- }
-
- return err;
- }
-